package bhwz.seac3.bl.query;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import bhwz.seac3.DBServiceManager;
import bhwz.seac3.blservice.datacomputer.PerGameTeamDataComputeBLService;
import bhwz.seac3.blservice.query.TeamQueryBLService;
import bhwz.seac3.dbservice.nbadata.SaveQueryDBService;
import bhwz.seac3.dbservice.nbadata.SeasonDBService;
import bhwz.seac3.dbservice.nbadata.TeamMatchDBService;
import bhwz.seac3.po.MatchPo;
import bhwz.seac3.po.TeamGameDataPo;
import bhwz.seac3.po.TeamIconPo;
import bhwz.seac3.po.TeamPo;
import bhwz.seac3.util.Decomposition;
import bhwz.seac3.util.ListSorter;
import bhwz.seac3.util.ListSorter.SortOrder;
import bhwz.seac3.util.TeamMatchWin;
import bhwz.seac3.vo.TeamVo;

public class TeamQueryBL extends UnicastRemoteObject implements
		TeamQueryBLService {

	PerGameTeamDataComputeBLService cbl;
	SaveQueryDBService<TeamPo> tdb;
	SaveQueryDBService<TeamGameDataPo> tddb;
	SaveQueryDBService<TeamIconPo> tidb;

	private static final long serialVersionUID = 1L;

	public TeamQueryBL(PerGameTeamDataComputeBLService cbl,
			SaveQueryDBService<TeamPo> tdb,
			SaveQueryDBService<TeamGameDataPo> tddb,
			SaveQueryDBService<TeamIconPo> tidb) throws RemoteException {
		super();
		this.cbl = cbl;
		this.tdb = tdb;
		this.tddb = tddb;
		this.tidb = tidb;
	}

	@Override
	public List<TeamVo> query赛季总数据(String season,
			Function<TeamVo, Comparable<?>> sortColumn, SortOrder order)
			throws Exception {
		return ListSorter.sort(get赛季总数据(season), sortColumn, order);
	}

	@Override
	public List<TeamVo> query场均数据(String season,
			Function<TeamVo, Comparable<?>> sortColumn, SortOrder order)
			throws Exception {
		return ListSorter.sort(get场均数据(season), sortColumn, order);
	}

	private List<TeamVo> get赛季总数据(String season) throws Exception {
		return queryAll(season, vo -> cbl.computeTeamDataAllGame(vo));
	}

	private List<TeamVo> get场均数据(String season) throws Exception {
		return queryAll(season, vo -> cbl.computeTeamDataPerGame(vo));
	}

	private List<TeamVo> queryAll(String season, Function<TeamVo, TeamVo> cmd)
			throws Exception {
		List<TeamGameDataPo> data = tddb.queryAll(TeamGameDataPo.class);
		List<TeamVo> dataInVo = new ArrayList<>();
		data.stream().filter(vo -> vo.get赛季().equals(season))
				.forEach(vo -> dataInVo.add(addPo2Vo(vo, null)));

		dataInVo.forEach(tv -> {
			TeamPo tqid = new TeamPo();
			tqid.set缩写(tv.get球队简称());
			try {
				addPo2Vo(tdb.queryById(tqid), tv);
			} catch (Exception e) {
				e.printStackTrace();
			}
		});

		List<TeamVo> result = new ArrayList<>();
		for (TeamVo vo : dataInVo) {
			result.add(cmd.apply(vo));
		}
		return result;
	}

	@Override
	public TeamVo query赛季总数据ByName(String nameOfTeam, String season)
			throws Exception {
		return queryById(nameOfTeam, season,
				vo -> cbl.computeTeamDataAllGame(vo));
	}

	@Override
	public TeamVo query场均数据ByName(String nameOfTeam, String season)
			throws Exception {
		return queryById(nameOfTeam, season,
				vo -> cbl.computeTeamDataPerGame(vo));
	}

	private TeamVo queryById(String nameOfTeam, String season,
			Function<TeamVo, TeamVo> cmd) throws Exception {
		TeamGameDataPo tgdqid = new TeamGameDataPo();
		tgdqid.set球队简称(nameOfTeam);
		tgdqid.set赛季(season);
		TeamGameDataPo data = tddb.queryById(tgdqid);
		TeamVo dataInVo = addPo2Vo(data, null);
		TeamVo result = cmd.apply(dataInVo);

		TeamPo tqid = new TeamPo();
		tqid.set缩写(nameOfTeam);
		addPo2Vo(tdb.queryById(tqid), result);
		TeamIconPo tiqid = new TeamIconPo();
		tiqid.setKey(nameOfTeam);
		addPo2Vo(tidb.queryById(tiqid), result);

		return result;
	}

	public static TeamVo addPo2Vo(TeamGameDataPo po, TeamVo vo) {
		if (vo == null)
			vo = new TeamVo();
		if (po == null)
			return vo;
		// TeamGameDataPo
		vo.set球队简称(po.get球队简称());
		vo.set胜利场数(po.get胜利场数());
		vo.set对手得分(po.get对手得分());
		vo.set对方防守篮板数(po.get对方防守篮板数());
		vo.set对手进攻篮板数(po.get对手进攻篮板数());
		vo.set进攻回合(po.get进攻回合());
		vo.set防守回合(po.get防守回合());
		// GameDataPo
		vo.set赛季(po.get赛季());
		vo.set比赛场数(po.get比赛场数());
		vo.set投篮数(po.get投篮数());
		vo.set罚球数(po.get罚球数());
		vo.set失误数(po.get失误数());
		vo.set断球数(po.get断球数());
		vo.set助攻数(po.get助攻数());
		vo.set盖帽数(po.get盖帽数());
		vo.set犯规数(po.get犯规数());
		vo.set比赛得分(po.get比赛得分());
		vo.set投篮命中数(po.get投篮命中数());
		vo.set三分命中数(po.get三分命中数());
		vo.set三分出手数(po.get三分出手数());
		vo.set罚球命中数(po.get罚球命中数());
		vo.set前场篮板数(po.get前场篮板数());
		vo.set后场篮板数(po.get后场篮板数());
		return vo;
	}

	public static TeamVo addPo2Vo(TeamPo po, TeamVo vo) {
		if (vo == null)
			vo = new TeamVo();
		if (po == null)
			return vo;
		vo.set球队全名(po.get球队全名());
		vo.set球队简称(po.get缩写());
		vo.set所在地(po.get所在地());
		vo.set赛区(po.get赛区());
		vo.set分区(po.get分区());
		vo.set主场(po.get主场());
		vo.set建立时间(po.get建立时间());
		return vo;
	}

	public static TeamVo addPo2Vo(TeamIconPo po, TeamVo vo) {
		if (vo == null)
			vo = new TeamVo();
		if (po == null)
			return vo;
		vo.setTeamIcon(po.getPicture());
		return vo;
	}

	@Override
	public List<TeamVo> query每场比赛表现(String season, TeamVo team)
			throws Exception {
		// TODO Auto-generated method stub
		TeamMatchDBService tdb = DBServiceManager.geTeamMatchDBService();
		List<MatchPo> m_po = tdb.getTeamMatchList(team.get球队简称(), season);
		Decomposition d=new Decomposition();
		return d.mtot(m_po, team.get球队简称());
	}

	@Override
	public List<TeamVo> query各个赛季表现(TeamVo team) throws Exception {
		// TODO Auto-generated method stub
		List<TeamVo> teamPerform=new LinkedList<TeamVo>();
		//Decomposition d=new Decomposition();
		
		TeamPo po=new TeamPo();
		po.set缩写(team.get球队简称());
		po.set赛区(team.get赛区());
		po.set所在地(team.get所在地());
		
		SeasonDBService sdb=DBServiceManager.getSeasonDBService();
		List<String> seasons=sdb.queryJoinedSeasons(po);
		Iterator<String> season=seasons.iterator();
		while(season.hasNext()){
			String temp=season.next();
			TeamVo vo=query场均数据(temp).stream().filter(t->t.get球队简称().equals(team.get球队简称())).collect(Collectors.toList()).get(0);
			teamPerform.add(vo);
		}
		
		return teamPerform;
	}

	@Override
	public Map<String, Double> query克制指数(TeamVo team) throws Exception {
		// TODO Auto-generated method stub
		String teamName=team.get球队简称();
        Map<String,Double> 克制指数=new HashMap<String,Double>();
        SeasonDBService sdb=DBServiceManager.getSeasonDBService();
        String season=null;
        try {
			season=sdb.queryAllSeasons().get(0);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        if(season==null){
        	return null;
        }
        TeamMatchDBService tmdb=DBServiceManager.geTeamMatchDBService();
        List<MatchPo> matches=tmdb.getTeamMatchList(team.get球队简称(), season);
        Iterator<MatchPo> itor=matches.iterator();
        Map<String,TeamMatchWin> temp=new HashMap<String,TeamMatchWin>();
        int win=0;
        int all=0;
        while(itor.hasNext()){
        	MatchPo mpo=itor.next();
            String team1=mpo.getTeam1();
            String team2=mpo.getTeam2();
            int score1=mpo.getTeam1Score();
            int score2=mpo.getTeam2Score();
            int winner=1;
            if(score1<score2){
            	winner=2;
            }
            if(team1.equals(teamName)){
            	if(winner==1){
            	  win++;
            	  if(temp.containsKey(team2)){
            		 TeamMatchWin tmw=temp.get(team2);
            		 tmw.LoseAGame();
            		 temp.replace(team2, tmw);
            	  }else{
            		 TeamMatchWin tmw=new TeamMatchWin();
            		 tmw.LoseAGame();
            		 temp.put(team2, tmw);
            	  }
            	}else{
            	  if(temp.containsKey(team2)){
            		  TeamMatchWin tmw=temp.get(team2);
            		  tmw.winAGame();
            		  temp.replace(team2, tmw);
            	  }else{
            		  TeamMatchWin tmw=new TeamMatchWin();
            		  tmw.winAGame();
            		  temp.put(team2, tmw);
            	  }
            	}
            }else{
            		if(winner==2){
                  	  win++;
                  	  if(temp.containsKey(team1)){
                  		 TeamMatchWin tmw=temp.get(team1);
                  		 tmw.LoseAGame();
                  		 temp.replace(team1, tmw);
                  	  }else{
                  		 TeamMatchWin tmw=new TeamMatchWin();
                  		 tmw.LoseAGame();
                  		 temp.put(team1, tmw);
                  	  }
                  	}else{
                  	  if(temp.containsKey(team1)){
                  		  TeamMatchWin tmw=temp.get(team1);
                  		  tmw.winAGame();
                  		  temp.replace(team1, tmw);
                  	  }else{
                  		  TeamMatchWin tmw=new TeamMatchWin();
                  		  tmw.winAGame();
                  		  temp.put(team1, tmw);
                  	  }
                  	}
            }
            all++;
        }
        double 本队胜率=win*1.0/all;
        for(String key:temp.keySet()){
        	String tname=key;
        	double idx=本队胜率-temp.get(key).getWinPer();
        	克制指数.put(tname, new Double(idx));
        }        
		return 克制指数;
	}
	
	
	
	

}
